/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef KH_SLE_SSAP_SERVER_H
#define KH_SLE_SSAP_SERVER_H
#include "sle_error_code.h"
#include "sle_ssap_config.h"
#include "sle_ssap_server_config.h"

#include <stdbool.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief The callback function of the Ssap server
 *
 * @param [in] errCode The error code of the operation
 * @param [in] serverId The ID of the server
 * @param [in] connectId The ID of the connection
 * @param [in] readCbPara The parameter of the read callback function
 * @return None
 */
typedef void (*SleReadRequestCallback)(SleErrorCode errCode, uint8_t serverId,
         uint16_t connectId, const SsapsReqReadCbParam *readCbPara);

/**
 * @brief The callback function of the Ssap server
 *
 * @param [in] errCode The error code of the operation
 * @param [in] serverId The ID of the server
 * @param [in] connectId The ID of the connection
 * @param [in] writeCbPara The parameter of the write callback function
 * @return None
 */
typedef void (*SleWriteRequestCallback)(SleErrorCode errCode, uint8_t serverId,
         uint16_t connectId, const SsapsReqWriteCbPara *writeCbPara);

/**
 * @brief The callback function of the Ssap server
 *
 * @param [in] errCode The error code of the operation
 * @param [in] serverId The ID of the connection
 * @param [in] mtuInfo The MTU info of the connection
 * @return None
 */
typedef void (*SleExchangeMtuInfo)(SleErrorCode errCode, uint8_t serverId, uint16_t connectId, const SsapMtuInfo *mtuInfo);

typedef struct {
    SleReadRequestCallback OnRequestReadCb;
    SleWriteRequestCallback OnRequestWriteCb;
    SleExchangeMtuInfo OnChangeMtuCb;
} SleSsapsCallbacks;

/**
 * @brief Initialize the Ssap server
 *
 * @param None
 * @return SleErrorCode
 */
SleErrorCode InitSleSsapsService(void);

/**
 * @brief Deinitialize the Ssap server
 *
 * @param None
 * @return SleErrorCode
 */
SleErrorCode DeinitSleSsapsService(void);

/**
 * @brief Add a Ssap server
 *
 * @param [in] appUuid The UUID of the server application
 * @param [out] serverId The ID of the server
 * @return SleErrorCode
 */
SleErrorCode AddSsapServer(const SleUuid *appUuid, uint8_t *serverId);

/**
 * @brief Remove a Ssap server
 *
 * @param [in] serverId The ID of the server
 * @return SleErrorCode
 */
SleErrorCode RemoveSsapServer(uint8_t serverId);

/**
 * @brief Create a service
 *
 * @param [in] serverId The ID of the server
 * @param [in] serviceUuid The UUID of the service
 * @param [in] isPrimary Whether the service is primary
 * @param [out] srviceHandle The handle of the service
 * @return SleErrorCode
 */
SleErrorCode AddService(uint8_t serverId, const SleUuid *serviceUuid, bool isPrimary, uint16_t *srviceHandle);

/**
 * @brief Add a property to a service
 *
 * @param [in] serverId The ID of the server
 * @param [in] serviceHandle The handle of the service
 * @param [in] param The parameter of the property
 * @param [out] propHandle The handle of the property
 * @return SleErrorCode
 */
SleErrorCode AddProperty(uint8_t serverId, uint16_t serviceHandle, const SsapsPropertyParam *propertyParam, uint16_t *propHandle);

/**
 * @brief Add a descriptor to a service
 *
 * @param [in] serverId The ID of the server
 * @param [in] serviceHandle The handle of the service
 * @param [in] propHandle The handle of the property
 * @param [in] descParam The parameter of the descriptor
 * @param [out] descHandle The handle of the descriptor
 * @return SleErrorCode
 */
SleErrorCode AddDescriptor(uint8_t serverId, uint16_t serviceHandle, uint16_t propHandle
        , const SsapsDescriptorParam *descParam, uint16_t *descHandle);

/**
 * @brief   Remove all services
 *
 * @param   [in] serverId The ID of the server
 * @return  SleErrorCode
 */
SleErrorCode RemoveAllServices(uint8_t serverId);

/**
 * @brief   Start a service
 *
 * @param   [in] serverId The ID of the server
 * @param   [in] serviceHandle The handle of the service
 * @return  SleErrorCode
 */
SleErrorCode StartService(uint8_t serverId, uint16_t serviceHandle);

/**
 * @brief Send a response
 *
 * @param [in] serverId The ID of the server
 * @param [in] connectId The ID of the connection
 * @param [in] param The parameter of the response
 * @return SleErrorCode
 */
SleErrorCode SendResponse(uint8_t serverId, uint16_t connectId, const SsapsSendRspParam *param);

/**
 * @brief Notify an indication
 *
 * @param [in] serverId The ID of the server
 * @param [in] connectId The ID of the connection
 * @param [in] param The parameter of the indication
 * @return SleErrorCode
 */
SleErrorCode NotifyIndicate(uint8_t serverId, uint16_t connectId, const SsapsNotifyParam *param);

/**
 * @brief Notify an indication by UUID
 *
 * @param [in] serverId The ID of the server
 * @param [in] connectId The ID of the connection
 * @param [in] param The parameter of the indication
 * @return SleErrorCode
 */
SleErrorCode NotifyIndicateByUuid(uint8_t serverId, uint16_t connectId, const SsapsNotyfyByUuidParam *param);

/**
 * @brief Set the MTU of the connection
 *
 * @param   [in] serverId The ID of the server
 * @param   [in] connectId The ID of the connection
 * @param   [in] mtuInfo The MTU info of the connection
 * @return  SleErrorCode
 */
SleErrorCode SetServerMtuInfo(uint8_t serverId, const SsapMtuInfo *mtuInfo);

/**
 * @brief Register the callback function of the Ssap server
 *
 * @param ssapsCallback The callback function of the Ssap server
 * @return SleErrorCode
 */
SleErrorCode RegisterSsapServerCallbacks(SleSsapsCallbacks *ssapsCallback);

/**
 * @brief Unregister the callback function of the Ssap server
 *
 * @param ssapsCallback The callback function of the Ssap server
 * @return SleErrorCode
 */
SleErrorCode UnregisterSsapServerCallbacks(SleSsapsCallbacks *ssapsCallback);

#ifdef __cplusplus
}
#endif
#endif